package com.atmilan.quartz.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import com.atmilan.quartz.utils.product.CarrottaProductUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.atmilan.quartz.constant.Constants;
import com.atmilan.quartz.constant.enums.ProductTypeEnum;
import com.atmilan.quartz.constant.enums.SyncStatusEnum;
import com.atmilan.quartz.model.dto.carotta.CarottaProductResDTO;
import com.atmilan.quartz.model.dto.carotta.CarottaProductResDTO.CarottaResp.Image;
import com.atmilan.quartz.model.dto.carotta.CarottaProductResDTO.CarottaResp.Option;
import com.atmilan.quartz.model.dto.carotta.CarottaProductResDTO.CarottaResp.Variant;
import com.atmilan.quartz.model.dto.crmeb.StoreProductCrmebRequest;
import com.atmilan.quartz.model.entity.Discount;
import com.atmilan.quartz.model.entity.carotta.CarottaProduct;
import com.atmilan.quartz.model.entity.carotta.CarottaProductSku;
import com.atmilan.quartz.model.entity.crmeb.StoreProduct;
import com.atmilan.quartz.model.entity.crmeb.SystemConfig;
import com.atmilan.quartz.service.IDiscountService;
import com.atmilan.quartz.service.ICarottaProductService;
import com.atmilan.quartz.service.ICarottaProductSkuService;
import com.atmilan.quartz.service.ICarottaSyncService;
import com.atmilan.quartz.service.IStoreProductService;
import com.atmilan.quartz.service.ISystemConfigService;
import com.atmilan.quartz.utils.RedisUtil;
import com.atmilan.quartz.utils.source.SourceCarottaProductUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class CarottaSyncServiceImpl implements ICarottaSyncService {

    @Autowired
    RedisUtil redisUtil;
    @Autowired
    ISystemConfigService systemConfigService;
    @Autowired
    ICarottaProductService carottaProductService;
    @Autowired
    ICarottaProductSkuService carottaProductSkuService;
    @Autowired
    IStoreProductService storeProductService;
    @Autowired
    SourceCarottaProductUtil sourceCarottaProductUtil;
    @Autowired
    IDiscountService discountService;
    @Autowired
    CarrottaProductUtil carrottaProductUtil;

    @Override
    public Boolean syncCarottaProduct() {
        //数据清空
        carottaProductService.deleteAll();
        carottaProductSkuService.deleteAll();

        int pageNo = 0;
        int pageSize = 50;
        long millis = System.currentTimeMillis();
        //页面ID
        String pageInfo = null;
        //计算总页数
        Integer count = carrottaProductUtil.getCarottaCount();
        int pageCount = (count + pageSize - 1) / pageSize;
        while (pageNo <= pageCount) {
            try {
                CarottaProductResDTO carottaProductResDTO = carrottaProductUtil.getCarottaProducts(pageSize, pageInfo);
                if (null == carottaProductResDTO || CollectionUtils.isEmpty(carottaProductResDTO.getProducts())) {
                    continue;
                }
                saveGoods(carottaProductResDTO);
                pageInfo = carottaProductResDTO.getPageInfo();
                log.info("--------------- Carotta远程抓取数据, 第: {} 页, 总共: {} 页, 总耗时: {} 分  ---------------", pageNo, pageCount, (int) ((System.currentTimeMillis() - millis) / 1000 / 60));
            } catch (Exception e) {
                e.printStackTrace();
                // 上面傻逼写的代码，死循环
                log.error("com.atmilan.quartz.service.impl.CarottaSyncServiceImpl.syncCarottaProduct erro",e);
            }finally {
                pageNo++;
            }
        }
        return true;
    }

    /**
     * 商品源数据保存
     *
     * @param carottaProductResDTO
     */
    private void saveGoods(CarottaProductResDTO carottaProductResDTO) {
        List<CarottaProduct> goodList = new ArrayList<>();
        List<CarottaProductSku> skuList = new ArrayList<>();
        carottaProductResDTO.getProducts().forEach(product -> {
            Map<String, Integer> map = product.getOptions().stream().collect(Collectors.toMap(o->o.getName().toLowerCase(), Option::getPosition));
            product.getVariants().forEach(sku -> {
                CarottaProductSku carottaProductSku = new CarottaProductSku();
                BeanUtils.copyProperties(sku, carottaProductSku);
                carottaProductSku.setSkuId(sku.getId());
                carottaProductSku.setSize(  null==map.get("size") ? null : getOptionByPosition(map.get("size"),sku) );
                carottaProductSku.setColor( null==map.get("color") ? null : getOptionByPosition(map.get("color"),sku) );
                skuList.add(carottaProductSku);
            });
            JSONArray images = JSONArray.parseArray(JSON.toJSONString(product.getImages().stream().map(Image::getSrc).collect(Collectors.toList())));
            CarottaProduct carottaProduct = new CarottaProduct();
            BeanUtils.copyProperties(product, carottaProduct);
            carottaProduct.setId(null).setProductId(product.getId()).setImages(images.toJSONString())
                    .setImage(Objects.isNull(product.getImage()) ? null : product.getImage().getSrc());
            goodList.add(carottaProduct);
        });
        carottaProductService.saveBatch(goodList);
        carottaProductSkuService.saveBatch(skuList);
    }

    private String getOptionByPosition(Integer position, Variant variant){
        String str = null;
        switch (position){
            case 1:
                str = variant.getOption1();
                break;
            case 2:
                str = variant.getOption2();
                break;
            case 3:
                str = variant.getOption3();
                break;
        }
        return str;
    }

    @Override
    public Boolean pushCarottaProduct() {
        try {
            //当次更新少于1千条, 则不更新, 并且重新拉取
            int count = carottaProductService.count();
            if(1000 > count){
                systemConfigService.update(Wrappers.<SystemConfig>lambdaUpdate()
                        .eq(SystemConfig :: getName, Constants.CAROTTA_SYNC_STATUS)
                        .set(SystemConfig :: getFormId, SyncStatusEnum.PUSH)
                        .set(SystemConfig :: getUpdateTime, new Date())
                );
                log.info("--------------- CAROTTA商品源数据, 少于规定条数, 不进行下发, 总条数为: {} ---------------", count);
                return false;
            }
            //将所有Carotta商品更新状态置为未更新
            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct :: getIsEurope, ProductTypeEnum.CAROTTA.getCode())
                    .set(StoreProduct :: getUpdateFlag, false)
            );

            //商品更新操作
            int pageNo = 1;
            int pageSize = 100;
            int maxPage = (count + pageSize - 1) / pageSize;
            log.info("--------------- 开始分页查询CAROTTA商品源数据, 本次更新总条数为: {} ---------------", count);

            List<Discount> discountList = discountService.list(Wrappers.lambdaQuery(Discount.class).eq(Discount::getType,ProductTypeEnum.CAROTTA.getCode()));
            long millis = System.currentTimeMillis();
            while (pageNo <= maxPage) {
                try {
                    PageHelper.startPage(pageNo, pageSize);
                    List<CarottaProduct> carottaProducts = carottaProductService.list();
                    PageInfo<CarottaProduct> pageInfo = PageInfo.of(carottaProducts);
                    List<CarottaProduct> products = pageInfo.getList();
                    buildProduct(products,discountList);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                log.info("--------------- CAROTTA下发商品到数据库, 当前页数: {}, 总页数: {}, 耗时: {} 分 ---------------", pageNo, maxPage, (int) ((System.currentTimeMillis() - millis) / 1000 / 60));
                pageNo++;
            }
            // 图搜删除
            storeProductService.delSeachImage(ProductTypeEnum.CAROTTA);
            // 下架所有未更新数据
            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct::getIsEurope, ProductTypeEnum.CAROTTA.getCode())
                    .eq(StoreProduct::getUpdateFlag, false)
                    .eq(StoreProduct :: getIsShow, true)
                    .eq(StoreProduct :: getIsDel, false)
                    .set(StoreProduct::getIsShow, false)
                    .set(StoreProduct::getStock, 0)
                    .set(StoreProduct::getLastPushTime, new Date())
                    .set(StoreProduct::getIsTusou, false)
                    );
            // 下架所有sku库存
            storeProductService.downloadSku(ProductTypeEnum.CAROTTA.getCode());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 商品构建处理
     * @param products
     */
    private void buildProduct(List<CarottaProduct> products,List<Discount> discountList) {
        try {
            for (CarottaProduct product : products) {
                //商品没有图片，跳过
                if(Objects.isNull(product.getImage())){
                    log.info("--------------- 该商品: {} 没有图片, 不进行下放 ---------------",product.getProductId());
                    continue;
                }
                List<CarottaProductSku> skus = carottaProductSkuService.list(Wrappers.<CarottaProductSku>lambdaQuery()
                        .eq(CarottaProductSku::getProductId, product.getProductId())
                        .isNotNull(CarottaProductSku::getSize)
                        .gt(CarottaProductSku::getInventoryQuantity, 0)
                );
                if (CollectionUtils.isEmpty(skus)) {
                    continue;
                }
                // 库存计算
                int stock = 0;
                List<CarottaProductSku> list = new ArrayList<>();
                for (CarottaProductSku sku : skus) {
                    if(ObjectUtils.isEmpty(sku.getPrice()) || sku.getPrice().compareTo(BigDecimal.ZERO) < 1){
                        log.info("--------------- 该商品：{}, sku: {} 售价异常, 不进行下放 ---------------",product.getProductId(),sku.getSkuId());
                        list.add(sku);
                        continue;
                    }
                    stock += sku.getInventoryQuantity();
                }
                skus.removeAll(list);
                if (CollectionUtils.isEmpty(skus)) {
                    continue;
                }
                if(stock == 0){
                    log.info("--------------- 该商品：{} 异常, 不进行下放 ---------------",product.getProductId());
                    continue;
                }

                // 构建实体
                StoreProductCrmebRequest storeProductCrmebRequest = sourceCarottaProductUtil.buildCarottaProduct(product, skus,discountList);
                // 数据保存
                StoreProduct storeProduct = storeProductService.getByBarCode(storeProductCrmebRequest.getBarCode(), storeProductCrmebRequest.getSuppliersId(), storeProductCrmebRequest.getKeyword());
                boolean crmebUpdate = true;
                if (null != storeProduct && null != storeProduct.getLastPushTime()) {
                    long txyye = (System.currentTimeMillis() - storeProduct.getLastPushTime().getTime()) / 1000 / 60;
                    if (60 > txyye) {
                        log.info("--------------- 该商品: {} 上次CAROTTA更新时间: {} 小于一小时, 不进行更新 ---------------", storeProductCrmebRequest.getBarCode(), storeProduct.getLastPushTime());
                        crmebUpdate = false;
                        storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                                .eq(StoreProduct::getId, storeProduct.getId())
                                .set(StoreProduct::getUpdateFlag, true)
                        );
                    }
                }
                if (crmebUpdate) {
                    storeProductService.saveOtProduct(storeProductCrmebRequest, storeProduct, stock);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}
